﻿//example   API缓存 过滤器 
var config;
var redisclient; // redisclient.getclient() 可直接获取reidis连接
module.exports = {
  grade: 2,
  //权重 值越小的优先执行
  check: function (req, res) { //检查是否符合过滤器要求  返回 true或false
    if (req.method == "GET") {
        //判断是否符合缓存规则
        if(config.apicache&&config.apicache[req.servername]){
            return  config.apicache[req.servername].some((v)=>{
                if (req.serverpath.search(v.path)!=-1){//符合条件
                  let query= copyobj(req.query)
                    if(v.ignore){//删除忽略参数 
                      let ignores=v.ignore.split(",");
                      ignores.some((v)=>{
                        delete query[v]
                      })
                    }
                    if(v.sessionfield){//登陆用户缓存
                      let sessionfield= v.sessionfield;
                      let session_id= getcookie(req.headers.cookie,sessionfield)||"" 
                      req.cachekey=`apicache:${req.servername}:${v.path}:${objtostring(query)}:${session_id}`
                    }else{
                      req.cachekey=`apicache:${req.servername}:${v.path}:${objtostring(query)}`
                    }
                  req.cachetime=v.maxAge||120
                  return true;
                } 
              })
        }else{
          return false
        }
    } else {
      return false
    }
  },
  callback: function (req, res, next) { //符合缓存规则的请求，从redis读数据，有数据（data和header）则直接返回，否则调用next执行下一个过滤器
     let key=req.cachekey;
     let redis= redisclient.getclient();
      redis.hgetall(key,(err,result)=>{
          if(err||!result){
            //console.log("nocache")
            next()
          }else{
              redis.ttl(key,(err,time)=>{
              let headers=JSON.parse(result.headers);
              let body=Buffer.from(result.body,"hex")
              headers.cacheage=time;//缓存失效时间
              res.set(headers)
              res.send(body);
              })
          }
      })
  },
  config: function (obj) { //如不需要读取服务网关的配置 可不设置此属性
    config = obj
  },
  setredis: function (client) { //如不需要使用redis数据库  可不设置此属性
    redisclient = client;
  }
}

function copyobj(obj) { //复制对象
  var copy = (obj instanceof Array) ? [] : {};
  for (attr in obj) {
    if (!obj.hasOwnProperty(attr)) continue;
    copy[attr] = (typeof obj[attr] == "object") ? copyobj(obj[attr]) : obj[attr];
  }
  return copy;
}

function objtostring(query){//参数对象转字符串

  return  Object.keys(query).sort().map((key)=>{
      return `${key}=${query[key]}`
    }).join("&")

}
function getcookie(cookie,filed){
    if(cookie && filed){
      let value="";
      cookie.split(";").some((v)=>{
            let aa=  v.split("=");
              if(aa&&aa.length>1){
                if(aa[0].trim()==filed.trim()){
                    value=aa[1];
                    return true;
                }
              }
      })
     return value; 
    }
}